{-
Module      : Data.Matrix.SmithNormalForm 
Description : A simple implementation of Smith normal form over the integers.
Copyright   : (c) Brian Hwang 2021
License     : MIT
Stability   : stable
-}
module Data.Matrix.SmithNormalForm
    ( smithNormalForm
    , invariantFactors
    ) where

import qualified Data.Matrix as M
import qualified Data.Vector as V

import qualified Data.Matrix.SmithNormalForm.Internal

-- | Returns the Smith normal form of an matrix, i.e. a diagonal matrix
-- obtained by applying elementary row and column operations
-- whose diagonal entries \([d_1,..,d_n]\) are such that \(d_k | d_{k+1}\)
-- (Does not assume that the matrix is square.)
smithNormalForm :: Integral a => M.Matrix a -> M.Matrix a
smithNormalForm = Data.Matrix.SmithNormalForm.Internal.smithNF 


-- | Given a matrix M, returns the invariant factors of M, i.e. the list of
-- diagonal entries of the Smith normal form of M.
invariantFactors :: Integral a => M.Matrix a -> [a]
invariantFactors = V.toList . M.getDiag . smithNormalForm
